iT邦幫忙

2022 iThome 鐵人賽

DAY 5
2
Software Development

30 天與九頭蛇先生做好朋友系列 第 5

Hydra 如何做到輕鬆導入

  • 分享至 

  • xImage
  •  

Hydra 提供了 Web 身分驗證(Authentication)與授權(Authorization)的解決方案。身分驗證與授權是兩個不一樣的行為,身分驗證的目的是要知道「你是誰?」,授權則是要知道「你能讓我做什麼?」。

現代的網路技術架構已非常成熟,包括身分驗證與授權的做法也有定義出完整的開放標準(Open standard),包括 Day02、Day03 的 OAuth 2.0 或是 Day04 的 OpenID Connect 都是開放標準,其他也有很多目前公認的標準做法都能在網路上查得到。開發者生態系受惠於開放標準,不管是哪個語言或產品服務,都有依照開放標準實作的套件與服務。這代表在基礎知識具備的前提下,從頭開始建置登入系統是非常清楚目標的。

但要能在沒有包袱的前提下從頭開始建置,是可遇不可求的夢想,而 Hydra 剛好是針對這個情境下設計的系統,它可以很容易地在既有的登入系統上架構起 OpenID Connect 服務提供者,這也是 Hydra 最具優勢的特色。

Hydra 怎麼做的?

Hydra 實作了目前主流的 OAuth 2.0 協定,和建構在此之上的 OpenID Connect 協定。這兩個協定舉例像 GitHub Authorizing OAuth Apps 是支援 OAuth 2.0 的協定,而 LINE Login 則是支援 OpenID Connect 協定。如果想要建立一個支援 OAuth 2.0 與 OpenID Connect 協定的身分驗證與授權中心,Hydra 完全可以做到,不僅如此,還非常簡單。

首先 Hydra 把整個登入流程分做兩個階段:LoginConsent,對應到本文一開始提到的「身分驗證」與「授權」兩個行為。另外還有一部分是 Logout,這個則是對應到 Day4 提到的狀態管理機制。

Hydra 在啟動登入流程開始的第一步,會轉導去自定義的 Login Provider,這個 provider 主要是做身分驗證,比方說使用帳號密碼做驗證,目的是要知道使用者是誰。驗證完成後,再由 Login Provider 通知 Hydra 做兩個主要的任務,一個是標記該使用者已完成驗證,以及使用者的唯一識別碼為何。

接著流程會換到自定義的 Consent Provider 處理授權相關的任務,這裡要做的事則是向使用者確認授權給應用程式的授權範圍,如 Email 或姓名資料等等。完成授權確認後,也是一樣由 Consent Provider 通知 Hydra 該使用者已完成授權,以及使用者授權的項目。

最後,登出的流程也是大同小異:先轉導到自定義的 Logout Provider 做自定義處理,如:清除指定 cookie。

在整個流程裡,上述三個自定義 Provider 可以處理各自的商業邏輯,比方說 Login Provider 可以在使用者沒有帳號的時候引導註冊新的。而完成流程只要通知並轉導 Hydra,再將流程交由 Hydra 控制即可完成整個 OpenID Connect 協定的流程。

實務上,在舊的登入系統裡,Login Provider 是可以直接使用原有的登入頁改寫--差異在於一開始進入登入頁,在驗證完成要通知 Hydra ,以及離開登入頁需要照 Hydra 流程進行。主要就是了解與修改這兩個關鍵點,就能很輕鬆地把 Hydra 導入既有系統。

互相傷害一下

沒有比較沒有傷害,來談談另一個同類型的開源產品來互相傷害。

筆者過去曾維護過 WSO2 Identity Server(以下簡稱 WSO2-IS)4.x 與 5.x 實作的 SAML 登入機制,5.x 版與 Hydra 同樣支援 OpenID Connect。它的設計是把使用者帳密資料表規劃在服務裡,因此使用它就必須轉換資料到服務資料庫裡。這樣的設計會帶來兩個困擾點:

  1. 開始使用它時,會需要轉換資料,以及習慣它的資料保存方法等。
  2. 不想使用它時,可能還會需要再轉換資料一次,以及執行後續遷移的策略等。

當時在使用 WSO2-IS 4.x 版時,是使用靠修改原始碼與調整 Schema 的方法完成客製化需求,像在串接第三方登入就非常的痛苦,要在龐大的原始碼庫中,找到正確的位置寫程式與建置專案是非常困難的。

後來改用 WSO2-IS 5.x 版時就比較好一點,存取帳密的方法可以改成客製的 User Management 以及客製的登入頁(使用 PHP)來存取自定義的 Database Schema,但這裡還是有幾個麻煩問題:

  1. 上面有提到「不想使用它(WSO2-IS 4.x)時」的代價,在從 4.x 升 5.x 完全體驗到這段痛苦,真的不要亂改官方的原始碼。為了相容「4.x 的客製」,在 5.x 一樣得在原始碼裡寫客製程式,包括第三方登入--即便 5.x 有提供了相對應的外掛,但客製過的就是不相容。
  2. WSO2-IS 是超大包的 Java,在這包 Java 裡寫客製程式是很痛苦的。

接著,在 WSO2-IS 5.x 上線一年後,認識了 Hydra,並在一次的機緣下,決定開始改用 Hydra。遷移的策略肯定是複雜的,畢竟是兩個完全不相容的系統;但相對的,建構在 Hydra 系統上的客製化程式,撰寫起來非常簡單,因為身分驗證的流程完全可以由自己控制,而且想要用什麼語言都沒問題的。

使用者資料庫?直接把 WSO2IS 5.x 的資料庫拿來用就好了呀!Hydra 的優點在此時此刻完全展現!

新版的 WSO2-IS 或許已經解決這些問題了,但筆者後來就沒有再確認過了。

Hydra 的缺點

評估技術一定要看缺點,它總是會在很奇妙的時機爆炸。
-- Miles,自己講的

Hydra 被設計成容易導入到各個既有系統中,實作導入過程很開心沒錯,但它有個致命的缺點--過多的轉導過程,造成網頁回應緩慢,影響使用者體驗。

舉例:一般網站在遇到需要做身分驗證的時候,只需要導頁至登入頁,打完帳密驗證完再轉導至對應頁面即可。把這段流程用甘特圖表現如下:

Image.jpeg

Hydra 呢,非常可怕。

Hydra 的設計是流程由 Hydra 啟動、控制與結束,所以有很多步驟需要再轉導到 Hydra,進而產生龐大的轉導開銷。一樣的例子,遇到需要做身分驗證時,第一步是轉導到 Hydra,從這步開始畫甘特圖:

Image.jpeg

如果所有使用者都有經過登入頁與授權頁的流程,其實問題並不大,最大的問題在於這兩個流程被省略的情境:把 OpenID Connect 作為單點登入(SSO)的解決方案,且剛好使用「記住我」的功能,接著又沒有必要的授權流程時,瀏覽器就得吃下 7 個轉導(不含登入頁與授權頁)才能進目標頁。筆電和桌電連線的速度比較快,一個轉導可能 50ms ~ 100ms 就搞定了,7 個轉導不到 1 秒就解決了;最怕的是極不穩定的行動網路,嚴重可能要到 300ms ~ 500ms,7 個轉導就要 3.5 秒,使用者體驗就會非常差。

即使 Hydra 是使用高效能高並發的 Golang 語言撰寫,仍然無法有效減少轉導過程的往返時間(round-trip time),這是選擇 Hydra 前,要考慮的重要問題。


上一篇
OpenID Connect 協定簡介
下一篇
Hydra 快速體驗
系列文
30 天與九頭蛇先生做好朋友23
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言